/*
 * GraphIOModule.cpp
 *
 *  Created on: 28-05-2012
 *      Author: Jakub Chomentowski
 */
#include "GraphIOModule.h"

void GraphIoModule::read(GraphDescriptor & descriptor, std::string path)
{
	FILE *graphFile = fopen(path.c_str(), "r");

	if (graphFile == NULL)
	{
		std::cout << "Niepoprawna sciezka do pliku" << std::endl;
		return;
	}

	if (fseek(graphFile, 0, SEEK_END))
	{
		std::cout << "Problem z przejsciem na koniec pliku" << std::endl;
		return;
	}

	long graphSize = ftell(graphFile) + 5;

	if (graphSize == 5)
	{
		std::cout << "plik z grafem jest pusty" << std::endl;
		return;
	}

	char *graphBuffer = new char[graphSize];

	if (fseek(graphFile, 0, SEEK_SET))
	{
		std::cout << "Problem z przejsciem na poczatek pliku" << std::endl;
		return;
	}

	std::string graphString("");

	while (fgets(graphBuffer, graphSize, graphFile))
	{
		graphString += graphBuffer;
	}

	fclose(graphFile);
	delete[] graphBuffer;

	graphBuffer = NULL;

	Json::Value graphRoot;

	if (!reader.parse(graphString, graphRoot))
	{
		std::cout << "Nieudane parsowanie" << std::endl;
		return;
	}

	std::cout << "Wynik po parsowaniu grafu" << std::endl << graphRoot.toStyledString();

	if (!graphRoot.isObject())
	{
		std::cout << "Bledny format danych 1" << std::endl;
		return;
	}

	if (!graphRoot["length"].isNumeric())
	{
		std::cout << "Bledny format danych 2" << std::endl;
		return;
	}

	if (!graphRoot["root_node"].isNumeric())
	{
		std::cout << "Bledny format danych 3" << std::endl;
		return;
	}

	if (!graphRoot["graph"].isArray())
	{
		std::cout << "Bledny format danych 4" << std::endl;
		return;
	}

	descriptor.length = graphRoot["length"].asInt();
	descriptor.rootNodeId = graphRoot["root_node"].asInt();

	for (int i = 0; i < graphRoot["graph"].size(); i++)
	{
		if (!graphRoot["graph"][i]["neighbours"].isArray() || !graphRoot["graph"][i]["weights"].isArray() || graphRoot["graph"][i]["neighbours"].size() != graphRoot["graph"][i]["weights"].size())
		{
			std::cout << "Bledny format danych 5" << std::endl;
			return;
		}

		descriptor.graph.push_back(std::pair<std::vector<int>, std::vector<int> >(std::vector<int>(), std::vector<int>()));

		for (int j = 0; j < graphRoot["graph"][i]["neighbours"].size(); j++)
		{
			descriptor.graph[i].first.push_back(graphRoot["graph"][i]["neighbours"][j].asInt());
			descriptor.graph[i].second.push_back(graphRoot["graph"][i]["weights"][j].asInt());
		}
	}
}

void GraphIoModule::write(GraphDescriptor &descriptor, std::string path, int result)
{
	Json::Value root;

	root["length"] = Json::Value(descriptor.length);

	root["root_node"] = Json::Value(descriptor.rootNodeId);

	if (result == SUCCESS)
		root["status"] = Json::Value("OK");
	if (result == ERROR)
		root["status"] = Json::Value("ERROR_LENGTH");

	root["graph"] = Json::Value(Json::arrayValue);

	for (int i = 0; i < descriptor.graph.size(); i++)
	{
		root["graph"].append(Json::Value(Json::objectValue));
		root["graph"][i]["neighbours"] = Json::Value(Json::arrayValue);
		root["graph"][i]["weights"] = Json::Value(Json::arrayValue);
		for (int j = 0; j < descriptor.graph[i].first.size(); j++)
		{
			root["graph"][i]["neighbours"].append(Json::Value(descriptor.graph[i].first[j]));
			root["graph"][i]["weights"].append(Json::Value(descriptor.graph[i].second[j]));
		}
	}

	std::cout << "otrymalem plik:" << std::endl << root.toStyledString();

	FILE *file = fopen(path.c_str(), "w");

	fputs(root.toStyledString().c_str(), file);

	fclose(file);
}

